package com.cfh.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Random;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;

import com.aia.prm.BeanFactory;
import com.cfh.domain.Config;
import com.cfh.domain.ConfigKey;
import com.cfh.persistence.dao.ConfigDAO;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
import com.thoughtworks.xstream.XStream;

public class Tools {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(Tools.class);

	private static String menuJson = null;
	private static Properties prop = new Properties();
	static {
		try {
			prop.load(Tools.class.getResourceAsStream("/website.properties"));
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e);
			throw new RuntimeException();
		}
	}

	public static String safe(Object o) {
		return o == null ? "" : o.toString();
	}

	public static void debugForJsp(String str) {
		logger.debug("debugForJsp(String) - start"); //$NON-NLS-1$
	}

	public static void errorForJsp(String str, Throwable e) {
		if (e == null) {
			logger.error(str);
		} else {
			logger.error("errorForJsp(String, Throwable)", null); //$NON-NLS-1$
		}

	}

	public static boolean isEmpty(String str) {
		if (str != null && !str.trim().equals("")) {
			return false;
		} else {
			return true;
		}
	}

	public static boolean hasText(String str) {
		if (str != null && !str.trim().equals("")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @return 得到20080412这样的8位日期
	 */
	public static String getToday() {
		String rt = "";
		Date dt = new Date();
		rt = Tools.date2Str(dt);
		return rt;
	}

	/**
	 * @return 得到当前日期的增量
	 * @param numberOfDays
	 *            增加的天数
	 */
	public static String getTodayDiff(int numberOfDays) {
		String rt = "";
		Date dt = new Date();
		Calendar ca = Calendar.getInstance();
		ca.setTime(dt);
		ca.add(Calendar.DATE, numberOfDays);
		rt = Tools.date2Str(ca.getTime());
		return rt;
	}

	/****
	 * 
	 * 得到120645这样的6位时间
	 * 
	 * @return
	 */
	public static String getTime() {
		String rt = "";
		Date dt = new Date();
		rt = Tools.time2Str(dt);
		return rt;
	}

	/***
	 * 得到20080412120645这样的14位时间
	 * 
	 * @return
	 */
	public static String getDateTime() {
		String rt = "";
		Date dt = new Date();
		rt = Tools.datetime2Str(dt);
		return rt;
	}

	public static void debug(String s) {

		System.out.println(s);

	}

	public static Date str2Date(String s) {
		Date dt = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
		if (s.length() == 6) {
			try {
				dt = formatter.parse(s);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return dt;
	}

	public static String date8todate10(String s) {
		Date dt = null;
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
		SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd");
		String s2 = "";
		try {
			dt = formatter.parse(s);
			s2 = formatter2.format(dt);
		} catch (ParseException e) {
			s2 = s;
		} finally {
			if (s2 == null || s2.trim().length() == 0)
				s2 = s;
		}
		return s2;

	}

	public static String newsDateFormat(String s) {
		Date dt = null;
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
		SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy.MM.dd");
		String s2 = "";
		try {
			dt = formatter.parse(s);
			s2 = formatter2.format(dt);
		} catch (ParseException e) {
			s2 = s;
		} finally {
			if (s2 == null || s2.trim().length() == 0)
				s2 = s;
		}
		return s2;

	}

	public static Date str2Datetime(String s) {
		Date dt = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
		if (s.length() == 14) {
			try {
				dt = formatter.parse(s);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return dt;
	}

	public static Date str2Time(String s) {
		Date dt = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("HHmmss");
		if (s.length() == 10) {
			try {
				dt = formatter.parse(s);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return dt;
	}

	/**
	 * 处理日期，返回6位String ,格式是yyyyMMdd
	 */
	public static String date2Str(Date dt) {
		String str = "";
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
		str = formatter.format(dt);
		return str;
	}

	public static String datetime2Str(Date dt) {
		String str = "";
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
		str = formatter.format(dt);
		return str;
	}

	public static String time2Str(Date dt) {
		String str = "";
		SimpleDateFormat formatter = new SimpleDateFormat("HHmmss");
		str = formatter.format(dt);
		return str;
	}

	/**
	 * trim字符串,如果参数为空则返回""
	 * 
	 */
	public static String trimStr(String str) {
		return str == null ? "" : str.trim();
	}

	/**
	 * 
	 * 得到配置的值
	 */
	public static String getProperties(String key) {

		return prop.getProperty(key);
	}

	public static String getWebRoot() {
		try {
			return System.getProperty(Tools.getProperties("system.rootkey"));
		} catch (Throwable e) {
			logger.error("Error when getWebRoot:" + e, e);
			return "";
		}

	}

	public static Date stringToDate(String s, String format) {
		Date dt = null;
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		try {
			dt = formatter.parse(s);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return dt;
	}

	/**
	 * 处理日期，返回6位String ,格式是yyyyMMdd
	 */
	public static String dateToString(Date dt, String format) {
		String str;
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		str = formatter.format(dt);
		return str;
	}

	public static String formatObjectToString(Object ob) {
		if (ob == null) {
			return "";
		} else {
			return ob.toString();
		}
	}

	public static String escapeHtml(Object ob) {
		if (ob == null) {
			return "";
		} else {
			return StringEscapeUtils.escapeHtml(ob.toString());
		}
	}

	public static String escapeBr(Object ob) {
		if (ob == null) {
			return "";
		} else {
			String result = String.valueOf(ob);
			result = result.replaceAll("\\r\\n", "<br />");
			result = result.replaceAll("\\n", "<br />");
			return result;
		}
	}

	public static String escapeJavaScript(Object ob) {
		if (ob == null) {
			return "";
		} else {
			return StringEscapeUtils.escapeJavaScript(ob.toString());
		}
	}

	public static void setMenuJson(String menuJson) {
		Tools.menuJson = menuJson;
	}

	public static String getMenuJson() {
		return menuJson;
	}

	public static String GUID() {
		try {
			Guid myGUID = new Guid();
			return myGUID.toString();
		} catch (Exception e) {
			return "FFFFFFFF";
		}
	}

	public static String randSixNumberString() {
		Random r = new Random();
		int i = r.nextInt(899999) + 100000;
		return String.valueOf(i);
	}

	/***
	 * 替代Struts2的标签功能，用以输出各种错误信息
	 * 
	 * @return
	 */
	public static String errorMessages() {
		StringBuffer errorString = null;
		String sucString = null;
		try {
			errorString = new StringBuffer();
			sucString = "true";
			ValueStack vc = ActionContext.getContext().getValueStack();

			// actionMessage Start
			List actionMessage = (List) vc.findValue("actionMessages");
			if (actionMessage != null) {
				for (Object o : actionMessage) {
					if (o != null) {
						errorString.append(o.toString() + " ");
					}
				}
			}
			// actionMessage End

			// actionErrors Start
			List list = (List) vc.findValue("actionErrors");
			if (list != null) {
				for (Object o : list) {
					if (o != null) {
						sucString = "false";
						errorString.append(o.toString() + " ");
					}
				}
			}
			// actionErrors End

			// fieldErrors Start
			Map<String, List> ferrors = (Map<String, List>) vc.findValue("fieldErrors");
			if (ferrors != null) {
				for (Map.Entry<String, List> entry : ferrors.entrySet()) {
					if (entry.getValue() != null && entry.getValue().get(0) != null) {
						sucString = "false";
						errorString.append(entry.getValue().get(0).toString() + " ");
					}
				}
			}
			// fieldErrors End

		} catch (Throwable e) {
			logger.debug("errorMessages()"); //$NON-NLS-1$
			errorString = new StringBuffer();
		}
		return errorString.toString();

	}

	/**
	 * 从消息类型来看，智能返回SUCCESS or INPUT.
	 * */
	public static String smartReturn(ActionSupport actionSupport) {
		Boolean isError = false;
		if (actionSupport.getActionErrors() != null && actionSupport.getActionErrors().size() > 0)
			isError = true;

		if (actionSupport.getFieldErrors() != null && actionSupport.getFieldErrors().size() > 0)
			isError = true;

		return isError ? actionSupport.INPUT : actionSupport.SUCCESS;
	}

	public static boolean isSuccess(ActionSupport actionSupport) {
		Boolean isError = false;
		if (actionSupport.getActionErrors() != null && actionSupport.getActionErrors().size() > 0)
			isError = true;

		if (actionSupport.getFieldErrors() != null && actionSupport.getFieldErrors().size() > 0)
			isError = true;

		return !isError;
	}



	/***
	 * 分享 protection_result.jsp
	 */
	public static void shareInit() {

		String share_title = "";
		String share_url = "";
		String share_content = "";
		String share_pic = "";

		try {
			share_url = java.net.URLEncoder.encode(getRoot() + "protection_result.jsp?guid=", "UTF-8");
		} catch (UnsupportedEncodingException e) {
			share_url = "";
			logger.error(e);
		}
		try {
			ServletActionContext.getRequest().setAttribute("share_title", share_title);
			ServletActionContext.getRequest().setAttribute("share_url", share_url);
			ServletActionContext.getRequest().setAttribute("share_content", share_content);
			ServletActionContext.getRequest().setAttribute("share_pic", share_pic);
		} catch (Exception e) {
			logger.error(e);
		}

	}

	/*
	 * 
	 * 分享我的明信片
	 */
	public static void shareInitMyMoment() {

		String share_title = "";
		String share_url = "";
		String share_content = "";
		String share_pic = "";

		try {
			share_url = java.net.URLEncoder.encode(getRoot(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			share_url = "";
			logger.error(e);
		}

		try {
			share_pic = java.net.URLEncoder.encode(getRoot() + "picThumb.jsp?id=", "UTF-8");
		} catch (UnsupportedEncodingException e) {
			share_pic = "";
			logger.error(e);
		}
		try {
			ServletActionContext.getRequest().setAttribute("share_title_mmt", share_title);
			ServletActionContext.getRequest().setAttribute("share_url_mmt", share_url);
			ServletActionContext.getRequest().setAttribute("share_content_mmt", share_content);
			ServletActionContext.getRequest().setAttribute("share_pic_mmt", share_pic);
		} catch (Exception e) {
			logger.error(e);
		}

	}

	/*
	 * 
	 * 分享主页
	 */
	public static void shareInitIndex() {

		String share_title = "";
		String share_url = "";
		String share_content = "";
		String share_pic = "";

		try {
			share_url = java.net.URLEncoder.encode(getRoot(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			share_url = "";
			logger.error(e);
		}

		try {
			ServletActionContext.getRequest().setAttribute("share_title_index", share_title);
			ServletActionContext.getRequest().setAttribute("share_url_index", share_url);
			ServletActionContext.getRequest().setAttribute("share_content_index", share_content);
			ServletActionContext.getRequest().setAttribute("share_pic_index", share_pic);
		} catch (Exception e) {
			logger.error(e);
		}

	}

	public static String URLEncode(String s) {
		if (s == null)
			return "";
		try {
			return java.net.URLEncoder.encode(s, "UTF-8");
		} catch (Exception e) {
			logger.error(e);
			return "";
		}
	}

	public static Map smartMap() {
		StringBuffer errorString = new StringBuffer();
		String sucString = "true";
		Map map = new HashMap();
		try {
			ValueStack vc = ActionContext.getContext().getValueStack();

			// actionMessage Start
			List actionMessage = (List) vc.findValue("actionMessages");
			if (actionMessage != null) {
				for (Object o : actionMessage) {
					if (o != null) {
						errorString.append(o.toString() + " ");
					}
				}
			}
			// actionMessage End

			// actionErrors Start
			List list = (List) vc.findValue("actionErrors");
			if (list != null) {
				for (Object o : list) {
					if (o != null) {
						sucString = "false";
						errorString.append(o.toString() + " ");
					}
				}
			}
			// actionErrors End

			// fieldErrors Start
			Map ferrors = (Map) vc.findValue("fieldErrors");
			if (ferrors != null) {
				for (Object o : ferrors.entrySet()) {
					Map.Entry entry = (Map.Entry) o;
					if (entry.getValue() != null) {
						List tmpList = (List) entry.getValue();
						if (entry.getValue() != null && tmpList.get(0) != null) {
							sucString = "false";
							errorString.append(tmpList.get(0).toString() + " ");
						}
					}
				}
			}
			// fieldErrors End
			map.put("success", sucString);
			map.put("message", errorString.toString());
		} catch (Throwable e) {
			map.put("success", "false");
			map.put("message", "Server Error");
			logger.error("smartMap()", e); //$NON-NLS-1$
		}
		return map;
	}

	/**
	 * 
	 * Safe Method
	 * 
	 * @param src
	 * @return
	 */
	public static String unescape(String src) {
		if (StringUtils.isEmpty(src)) {
			return "";
		}
		StringBuffer tmp = new StringBuffer();
		tmp.ensureCapacity(src.length());
		int lastPos = 0, pos = 0;
		char ch;
		while (lastPos < src.length()) {
			pos = src.indexOf("%", lastPos);
			if (pos == lastPos) {
				if (src.charAt(pos + 1) == 'u') {
					ch = (char) Integer.parseInt(src.substring(pos + 2, pos + 6), 16);
					tmp.append(ch);
					lastPos = pos + 6;
				} else {
					ch = (char) Integer.parseInt(src.substring(pos + 1, pos + 3), 16);
					tmp.append(ch);
					lastPos = pos + 3;
				}
			} else {
				if (pos == -1) {
					tmp.append(src.substring(lastPos));
					lastPos = src.length();
				} else {
					tmp.append(src.substring(lastPos, pos));
					lastPos = pos;
				}
			}
		}
		return tmp.toString();
	}

	public static String unescapeTwice(String s) {
		return unescape(unescape(s));
	}

	public static String escape(String src) {
		int i;
		char j;
		StringBuffer tmp = new StringBuffer();
		tmp.ensureCapacity(src.length() * 6);
		for (i = 0; i < src.length(); i++) {
			j = src.charAt(i);
			if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j))
				tmp.append(j);
			else if (j < 256) {
				tmp.append("%");
				if (j < 16)
					tmp.append("0");
				tmp.append(Integer.toString(j, 16));
			} else {
				tmp.append("%u");
				tmp.append(Integer.toString(j, 16));
			}
		}
		return tmp.toString();
	}

	public static void main(String[] args) {
		String tmp = "~!@#$%^&*()_+|\\=-,./?><;'][{}\"";
		System.out.println("testing escape : " + tmp);
		tmp = escape(tmp);
		System.out.println(tmp);
		System.out.println("testing unescape :" + tmp);
		System.out.println(unescape(tmp));
	}

	public static String newsContentFormat(String s) {
		if (StringUtils.isEmpty(s))
			return "";
		String newStr = s.replaceAll("\r\n", "<br />");
		newStr = newStr.replaceAll("\n", "<br />");

		return newStr;
	}

	public static String getRoot() {
		try {
			return getProperties("mail.websiteurl");
		} catch (Exception e) {
			logger.error(e);
			return "";
		}
	}

	public static String makeIPAddress() {
		try {
			return ServletActionContext.getRequest().getRemoteAddr();
		} catch (Exception e) {
			logger.warn("makeIPAddress:" + e, e);
			return "";
		}
	}

	public static String dumpObjectToXML(Object obj) {
		if (obj == null)
			return "";

		try {
			XStream xstrea = new XStream();
			return xstrea.toXML(obj);
		} catch (Throwable e) {
			logger.warn("Err when dumpObjectToXML:" + e, e);
			return "";
		}

	}

	public static String formatBigDecimal(BigDecimal bigDecimal) {
		if (bigDecimal == null) {
			return "";
		}
		try {
			NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
			numberFormat.setMaximumFractionDigits(2);
			return numberFormat.format(bigDecimal.doubleValue());
		} catch (Exception e) {
			logger.warn("Err when formatBigDecimal:" + e, e);
			return String.valueOf(bigDecimal);
		}

	}
	public static String formatNumber(Number bigDecimal) {
		if (bigDecimal == null) {
			return "";
		}
		try {
			NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
			numberFormat.setMaximumFractionDigits(2);
			return numberFormat.format(bigDecimal.doubleValue());
		} catch (Exception e) {
			logger.warn("Err when formatBigDecimal:" + e, e);
			return String.valueOf(bigDecimal);
		}
		
	}

	public static String getDatabaseProperty(String type, String code) {
		ConfigDAO configDAO = (ConfigDAO) BeanFactory.get().getBean("configDAO");
		if (configDAO == null) {
			throw new RuntimeException("Can not find configDAO");
		}
		ConfigKey key = new ConfigKey();
		key.setCFG_CODE(code);
		key.setCFG_TYPE(type);
		Config config = configDAO.selectByPrimaryKey(key);
		if (config == null) {
			throw new RuntimeException("Can not find this config:" + type + "," + code);
		}

		if (Tools.hasText(config.getCFG_VALUE())) {
			return config.getCFG_VALUE().trim();
		} else {
			return "";
		}
	}
	
	public static String getDatabaseText(String type, String code) {
		ConfigDAO configDAO = (ConfigDAO) BeanFactory.get().getBean("configDAO");
		if (configDAO == null) {
			throw new RuntimeException("Can not find configDAO");
		}
		ConfigKey key = new ConfigKey();
		key.setCFG_CODE(code);
		key.setCFG_TYPE(type);
		Config config = configDAO.selectByPrimaryKey(key);
		if (config == null) {
			throw new RuntimeException("Can not find this config:" + type + "," + code);
		}

		if (Tools.hasText(config.getCFG_FREETEXT3())) {
			return config.getCFG_FREETEXT3().trim();
		} else {
			return "";
		}
	}

	/**
	 * 
	 * @param type
	 *            |code|defaultValue
	 * @return
	 */
	public static String getSafeDatabaseProperty(String mixValue) {
		String[] array = null;
		try {
			array = mixValue.split("\\|");
			return getDatabaseProperty(array[0], array[1]);
		} catch (Exception e) {
			if (array != null && array.length >= 3) {
				return array[2];
			} else {
				return "";
			}
		}
	}
	
	/**
	 * 
	 * @param type
	 *            |code|defaultValue
	 * @return
	 */
	public static String getSafeDatabaseText(String mixValue) {
		String[] array = null;
		try {
			array = mixValue.split("\\|");
			return getDatabaseText(array[0], array[1]);
		} catch (Exception e) {
			if (array != null && array.length >= 3) {
				return array[2];
			} else {
				return "";
			}
		}
	}

	/**
	 * 序列化方式克隆，如果出错则返回空
	 * 
	 * @param fromObj
	 * @return
	 */
	public static Object doClone(Object fromObj) {
		if (fromObj == null) {
			return null;
		}
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		Object result = null;
		try {
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(fromObj);
			oos.close();

			ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
			ObjectInputStream ois = new ObjectInputStream(bais);
			result = ois.readObject();
			ois.close();
		} catch (Exception e) {
			logger.warn("clone failed!", e);
			return null;
		}
		return result;
	}

}
